/* ACW Tunes
 * Joe Pardue May 13, 2009
 * based on Arduino example code Melody
 * http://www.arduino.cc/en/Tutorial/Melody
 * (cleft) 2005 D. Cuartielles for K3
 */
// Note to more experienced programmers - yes I know this
// isn't the 'best' way to do this, but this is instructional
// code for novices.
//
// Each of the tunes repeats sections of code
// that could be combined for more economical use of resources
// but such combination might obscure things for novices.
// Eventually, we would use pointers to the tune arrays
// and play them within a single function. We would also store
// the tune data in AVR program memory.

// The following is copied from D. Cuartielles Melody example:
// BEGIN COPY
/* 
 * This example uses a piezo speaker to play melodies.  It sends
 * a square wave of the appropriate frequency to the piezo, generating
 * the corresponding tone.
 *
 * The calculation of the tones is made following the mathematical
 * operation:
 *
 *       timeHigh = period / 2 = 1 / (2 * toneFrequency)
 *
 * where the different tones are described as in the table:
 *
 * note 	frequency 	period 	timeHigh
 * c 	        261 Hz 	        3830 	1915 	
 * d 	        294 Hz 	        3400 	1700 	
 * e 	        329 Hz 	        3038 	1519 	
 * f 	        349 Hz 	        2864 	1432 	
 * g 	        392 Hz 	        2550 	1275 	
 * a 	        440 Hz 	        2272 	1136 	
 * b 	        493 Hz 	        2028	1014	
 * C	        523 Hz	        1912 	956
 *
 */
// END COPY

#include "libACW001.h"

// define numbers for tunes
#define Twinkle 0
#define Happy_Birthday 1
#define Euro_Siren 2
#define Twirdle 3
#define Beep_Beep 4

// create and intialize global variables
int speakerPin = 9; // pin to drive the piezo element
int tune = 0; // tune to play

int main(void)
{
	init();

	setup();
    
	for (;;)
		loop();
        
	return 0;
}

void setup() {
  //Serial.begin(9600);
  serialBegin(9600); 
  pinMode(speakerPin, OUTPUT);
  
  // greetings
  /*Serial.println("TAW Tunes");
  Serial.println("Enter 0 for Twinkle Twinkle Little Star");
  Serial.println("Enter 1 for Happy Birthday");
  Serial.println("Enter 2 for Euro Siren");
  Serial.println("Enter 3 for Twerdle Alarm");
  Serial.println("Enter 4 for Beep Alarm");*/
  printf("ACW Tunes\n");
  printf("Enter 0 for Twinkle Twinkle Little Star\n");
  printf("Enter 1 for Happy Birthday\n");
  printf("Enter 2 for Euro Siren\n");
  printf("Enter 3 for Twerdle Alarm\n");
  printf("Enter 4 for Beep Alarm\n");
}

void loop() {
  // check if data has been sent from the computer
  //if (Serial.available()) {
  if (serialAvailable()) {
    cmdParse(); // if true, get the data and parse it
  }
}

// use a switch statement to decide which tune to play
void cmdParse()
{
  //tune = Serial.read(); 
  tune = serialRead(); 
  
  switch(tune)
  {
    case '0':
      play_Twinkle();
      break;
    case '1':
      play_Happy();
      break;
    case '2':
      play_Euro();
      break;
    case '3':
      play_Twerdle();
      break;
    case '4':
      play_Beep();
      break;
    default:
      //Serial.print("TAW Invalid tune: ");
      //Serial.println(tune, BYTE);
	  printf("Invalid tune: %c",tune);
      break;      
  }
}

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
  
  // play the tone corresponding to the note name
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

//Twinkle
int Twinkle_length = 15; // the number of notes
char Twinkle_notes[] = "ccggaagffeeddc "; // a space represents a rest
int Twinkle_beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int Twinkle_tempo = 300;
void play_Twinkle()
{
  for (int i = 0; i < Twinkle_length; i++) {
    if (Twinkle_notes[i] == ' ') {
      delay(Twinkle_beats[i] * Twinkle_tempo); // rest
    } else {
      playNote(Twinkle_notes[i], Twinkle_beats[i] * Twinkle_tempo);
    }
    
    // pause between notes
    delay(Twinkle_tempo / 2);   
  }
}

//Happy Birthday
int Happy_length = 26; // the number of notes
char Happy_notes[] = "ccdcfeccdcgfccCafedbbafgf "; // a space represents a rest
int Happy_beats[] = { 1, 1, 2, 2, 2, 4, 1, 1, 2, 2, 2, 4, 1, 1, 2, 2, 2, 2, 6, 1, 1, 2, 2, 2, 2, 4 };
int Happy_tempo = 150;
void play_Happy()
{
  for (int i = 0; i < Happy_length; i++) {
    if (Happy_notes[i] == ' ') {
      delay(Happy_beats[i] * Happy_tempo); // rest
    } else {
      playNote(Happy_notes[i], Happy_beats[i] * Happy_tempo);
    }
    
    // pause between notes
    delay(Happy_tempo / 2);  
  }  
}

//Euro Siren
int Euro_length = 2; // the number of notes
char Euro_notes[] = "Cc"; // a space represents a rest
int Euro_beats[] = { 3, 3 };
int Euro_tempo = 150;
void play_Euro()
{ 
  // play it 10 times
  for(int j = 0 ; j < 10; j++){
  for (int i = 0; i < Euro_length; i++) {
    if (Euro_notes[i] == ' ') {
      delay(Euro_beats[i] * Euro_tempo); // rest
    } else {
      playNote(Euro_notes[i], Euro_beats[i] * Euro_tempo);
    }
    
    // pause between notes
    delay(Euro_tempo / 2); 
  }
  }  
}

//Twerdle 
int Twerdle_length = 16; // the number of notes
char Twerdle_notes[] = "cdefgabCCbagfedc"; // a space represents a rest
int Twerdle_beats[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
int Twerdle_tempo = 50;
void play_Twerdle()
{
  // play it 10 times
  for(int j = 0 ; j < 10; j++){
  for (int i = 0; i < Twerdle_length; i++) {
    if (Twerdle_notes[i] == ' ') {
      delay(Twerdle_beats[i] * Twerdle_tempo); // rest
    } else {
      playNote(Twerdle_notes[i], Twerdle_beats[i] * Twerdle_tempo);
    }
    
    // pause between notes
    delay(Twerdle_tempo / 2); 
  } 
  }  
}

//Beep Beep
int Beep_length = 4; // the number of notes
char Beep_notes[] = "CC "; // a space represents a rest
int Beep_beats[] = { 4,4,1  };
int Beep_tempo = 300;
void play_Beep()
{
  // play it 10 times
  for(int j = 0 ; j < 10; j++){  
  for (int i = 0; i < Beep_length; i++) {
    if (Beep_notes[i] == ' ') {
      delay(Beep_beats[i] * Beep_tempo); // rest
    } else {
      playNote(Beep_notes[i], Beep_beats[i] * Beep_tempo);
    }
    
    // pause between notes
    delay(Beep_tempo / 2); 
  }
  }   
}
